home *** CD-ROM | disk | FTP | other *** search
- {$D-,L-,I-,R-,S-,F-,B-,V-,O-,N-,E+,A+,X+}
- {$M $2000,0,0}
- {…ÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕª}
- {∫ Archiv v2.03 Backup/Restore database utility (TurboPascal v6.0) ∫}
- {∫ (c) 1991, JHK, JHK-Software, Piestany. ∫}
- {»ÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕº}
-
- program Archiv; {Warning! Boolean evaluation must be short circuit ($B-)}
- {Warning! Input output checking must be disabled ($I-)}
- uses
- Crt,
- Dos;
-
-
- {$IfDef ENGLISH}
- const
- not_create = 'Can''t create file ';
- not_open = 'Can''t open file ';
- not_read = 'Can''t read file ';
- not_write = 'Can''t write file ';
- not_close = 'Can''t close file ';
- insert_new = 'Insert new diskette ';
- into_drive = 'into drive ';
- then_text = 'then ';
- press_key = 'press any key...';
- insert_archiv = 'Insert archiv diskette ';
- disk_full = 'Disk full or not formatted!';
- insert_another = 'Insert another disk and press <Enter>, or press <Esc> for Abort...';
- canceled = 'Canceled by operator!';
- archiv_error = 'Archiv error! ';
- save_into = 'Save files into ';
- restore_from = 'Restore files from ';
- split = '(split)';
- continue = '(continue)';
- syntax1 = 'Syntax is: Archiv [/W[nnn]] /S[ave] InputFiles ArchivFile <Enter>';
- syntax2 = ' or: Archiv [/W[nnn]] /L[oad] ArchivFile [OutputDir] <Enter>';
- syntax3 = 'Wnnn: W=windowed_output; nnn=Dos_color_attribute_(0-255)';
- done = 'Done.';
-
- {$Else}
-
- const
- not_create = 'Nemozem vytvorit subor ';
- not_open = 'Nemozen otvorit subor ';
- not_read = 'Nemozem citat subor ';
- not_write = 'Nemozem zapisovat do suboru ';
- not_close = 'Nemozem zatvorit subor ';
- insert_new = 'Vlozte novu disketu ';
- into_drive = 'do mechaniky ';
- then_text = 'potom ';
- press_key = 'stlacte nejaku klavesu...';
- insert_archiv = 'Vlozte archivnu disketu ';
- disk_full = 'Disk(disketa) je plny alebo nenaformatovany!';
- insert_another = 'Vlozte iny disk a stlacte <Enter>, alebo stlacte <Esc> pre koniec...';
- canceled = 'Ukoncene operatorom!';
- archiv_error = 'Chyba! ';
- save_into = 'Ulozenie suborov do ';
- restore_from = 'Obnovenie suborov z ';
- split = '(rozdeleny)';
- continue = '(pokracovanie)';
- syntax1 = 'Syntax je: Archiv [/W[nnn]] /S[ave] VstupneSubory ArchivnySubor <Enter>';
- syntax2 = ' Archiv [/W[nnn]] /L[oad] ArchivnySubor [VystupnyAdresar] <Enter>';
- syntax3 = 'Wnnn: W=vystup_do_okna; nnn=Dos_cislo_farby_(0-256)';
- done = 'Ok.';
- {$EndIf}
-
-
- const
- c_byte=221; {magic compress byte indicator}
- BufSize=4096+512;
- cr_lf=#13#10;
-
- type
- TiBuf=array[1..BufSize+1] of Byte;
- ToBuf=array[1..2*BufSize+1] of Byte;
-
- const
- ArchOpened:Boolean=false;
- FreeSpace:LongInt=0;
-
- var
- iBuf:TiBuf;
- oBuf:ToBuf;
- Fi,Fo:File;
- D,N,E:PathStr; {directory info, see FSplit()}
- S,FNi,FNo:String;
- OutDir:PathStr; {for Load}
- UpPressKey:PathStr; {Upper case message "Press any key..."}
-
-
- procedure Abort(Msg:String);
- begin {Abort}
- Write(cr_lf,archiv_error,Msg);
- Write(cr_lf,UpPressKey);
- ReadKey;
- Halt(1);
- end;{Abort}
-
-
- procedure AbortPars;
- begin {AbortPars}
- Write(cr_lf,syntax1);
- Write(cr_lf,syntax2);
- Write(cr_lf,syntax3);
- Halt(1);
- end;{AbortPars}
-
-
- function StUpCase(S:String):String;
- var
- I:Integer;
- begin {StUpCase}
- for I:=1 to Length(S) do S[I]:=UpCase(S[I]);
- StUpCase:=S;
- end;{StUpCase}
-
-
- function DiskSize(D:Char):LongInt;
- begin {DiskSize}
- DiskSize:=DiskFree(Ord(UpCase(D))-Ord('A')+1)-2; {2 bytes for saving close info}
- end;{DiskSize}
-
-
- function S_OpenArchiv(FName:PathStr):LongInt;
- var
- Ch:Char;
- L:LongInt;
- I,Code:Integer;
- begin {S_OpenArchiv}
- if E<>'.001' then Write(' ',split);
- if UpCase(FNo[1]) in ['A','B'] then begin
- Write(cr_lf,insert_new,into_drive,UpCase(FNo[1]),': ',then_text,press_key);
- ReadKey;
- end;{if}
- Assign(Fo,FNo);
- ReWrite(Fo,1);
- if IoResult<>0 then Abort(not_create+FNo);
- L:=DiskSize(FNo[1]);
- while L<512 do begin
- Write(cr_lf,disk_full);
- Write(cr_lf,insert_another);
- repeat
- Ch:=UpCase(ReadKey);
- until Ch in [#13,#27];
- if Ch=#27 then Abort(canceled);
- Assign(Fo,FNo);
- ReWrite(Fo,1);
- if IoResult<>0 then Abort(not_create+FNo);
- L:=DiskSize(FNo[1]);
- end;{while}
- S_OpenArchiv:=L;
- ArchOpened:=true;
- Write(cr_lf,save_into,FNo);
- if E<>'.001' then Write(cr_lf,' ',FName,' ',continue);
- end;{S_OpenArchiv}
-
-
- procedure S_CloseArchiv(lContinue:Boolean);
- var
- B:Byte;
- i,Code:Integer;
- begin {S_CloseArchiv}
- Val(Copy(E,2,3),B,Code);
- Inc(B);
- Str(B:3,E);
- for i:=1 to Length(E) do if E[i]=' ' then E[i]:='0';
- E:='.'+E;
- FNo:=D+N+E;
- FillChar(oBuf[1],2,0);
- if lContinue then oBuf[2]:=B;
- BlockWrite(Fo,oBuf,2,Code);
- Close(Fo);
- if (IoResult<>0)or(2<>Code) then Abort(not_close+FNo);
- ArchOpened:=false;
- end;{S_CloseArchiv}
-
-
- function Compress(Bti:Word):Word;
- var
- i,j,Bto:Word;
- begin {Compress}
- i:=1;
- j:=2;
- Bto:=1;
- while (i<=Bti) do begin
- while (j<=Bti)and(iBuf[i]=iBuf[j]) do Inc(j); {search unique bytes}
- if (i+2)<j then begin {save block}
- while i<j do begin
- oBuf[Bto]:=c_byte; Inc(Bto); {magic compress byte indicator}
- oBuf[Bto]:=iBuf[i]; Inc(Bto); {origin byte}
- if (j-i)>255 then begin
- oBuf[Bto]:=255; Inc(Bto); {count for orgin byte}
- Inc(i,255);
- end else begin
- oBuf[Bto]:=j-i; Inc(Bto); {count for orgin byte}
- i:=j;
- end;{if}
- end;{while}
- Inc(j);
- end else if iBuf[i]=c_byte then begin {save bad block}
- oBuf[Bto]:=c_byte; Inc(Bto); {magic compress byte indicator}
- oBuf[Bto]:=c_byte; Inc(Bto); {origin byte}
- oBuf[Bto]:=j-i; Inc(Bto); {count for orgin byte}
- i:=j;
- Inc(j);
- end else begin {save one/two byte(s)}
- oBuf[Bto]:=iBuf[i]; Inc(Bto); Inc(i);
- while i<j do begin
- oBuf[Bto]:=iBuf[i]; Inc(Bto); Inc(i);
- end;{while}
- Inc(j);
- end;{if}
- end;{while}
- Compress:=Bto-1;
- end;{Compress}
-
-
- function S_SaveBytes(W:LongInt):LongInt; {return saved_bytes}
- var
- Bti,Bto,Count:Word;
- Saved:LongInt;
- begin {S_SaveBytes}
- Saved:=0;
- repeat
- if BufSize<W then Bti:=BufSize else Bti:=W;
- BlockRead(Fi,iBuf,Bti,Count);
- if (IoResult<>0)or(Bti<>Count) then Abort(not_read+FNi);
- Bto:=Compress(Bti);
- BlockWrite(Fo,oBuf,Bto,Count);
- if (IoResult<>0)or(Bto<>Count) then Abort(not_write+FNo);
- Dec(W,Bti);
- Inc(Saved,Bto);
- until W=0;
- S_SaveBytes:=Saved;
- end;{S_SaveBytes}
-
-
- procedure S_SaveFile(FName:PathStr);
- var
- i:Integer;
- Count:Word;
- Wi,Wo,BytesNeedSave:LongInt;
- SaveFName,SaveFExt,S:PathStr;
- begin {S_SaveFile}
- Assign(Fi,FName);
- Reset(Fi,1);
- if IoResult<>0 then Abort(not_open+FName);
- BytesNeedSave:=FileSize(Fi);
- if not(ArchOpened) then
- FreeSpace:=S_OpenArchiv(FName)
- else begin
- if FreeSpace<512 then begin
- S_CloseArchiv(true);
- FreeSpace:=S_OpenArchiv(FName);
- end;{if}
- end;{if}
- Write(cr_lf,' ',FName);
- FSplit(FName,S,SaveFName,SaveFExt);
- SaveFName:=SaveFName+SaveFExt;
- i:=Length(SaveFName);
- Move(SaveFName,oBuf[1],i+1);
- Move(BytesNeedSave,oBuf[i+2],4); Inc(i,5);
- BlockWrite(Fo,oBuf,i,Count);
- if (IoResult<>0)or(i<>Count) then Abort(not_write+FNo);
- repeat
- if not(ArchOpened) then FreeSpace:=S_OpenArchiv(FName);
- if FreeSpace<BytesNeedSave then Wi:=FreeSpace else Wi:=BytesNeedSave;
- Wo:=S_SaveBytes(Wi);
- Dec(BytesNeedSave,Wi);
- Dec(FreeSpace,Wo);
- if (FreeSpace<512)and(BytesNeedSave<>0) then S_CloseArchiv(true);
- until BytesNeedSave=0;
- Close(Fi);
- end;{S_SaveFile}
-
-
- procedure S_SaveMask(Mask:PathStr);
- var
- Sr:SearchRec;
- Di,Na,Ex:PathStr;
- begin {S_SaveMask}
- FSplit(Mask,Di,Na,Ex);
- FindFirst(Mask,AnyFile,Sr);
- while DosError=0 do begin
- if (Sr.Name[1]<>'.')and((Sr.Attr and $18)=0) then S_SaveFile(Di+Sr.Name);
- FindNext(Sr);
- end;{while}
- end;{S_SaveMask}
-
-
- procedure L_OpenArchiv;
- var
- Ch:Char;
- begin {L_OpenArchiv}
- Assign(Fi,FNi);
- if UpCase(FNi[1]) in ['A','B'] then begin
- Write(cr_lf,insert_archiv,Copy(E,2,3),' ',into_drive,UpCase(FNi[1]),': ',then_text,press_key);
- ReadKey;
- ReSet(Fi,1);
- if IoResult<>0 then begin
- repeat
- Write(cr_lf,not_open,FNi);
- Write(cr_lf,insert_another);
- repeat
- Ch:=UpCase(ReadKey);
- until Ch in [#13,#27];
- if Ch=#27 then Abort(canceled);
- ReSet(Fi,1);
- until IoResult=0;
- end;{if}
- end else begin {hard disk}
- ReSet(Fi,1);
- if IoResult<>0 then Abort(not_open+FNi);
- end;{if}
- Write(cr_lf,restore_from,FNi);
- if E<>'.001' then Write(cr_lf,' ',FNo,' ',continue);
- end;{L_OpenArchiv}
-
-
- function L_CloseArchiv:Boolean;
- var
- B:Byte;
- i,j,Code:Integer;
- begin {L_CloseArchiv}
- BlockRead(Fi,I,2,Code);
- Close(Fi);
- if (IoResult<>0)or(2<>Code) then Abort(not_close+FNi);
- L_CloseArchiv:=(I=0);
- {}
- Val(Copy(E,2,3),B,Code); {next archiv extension}
- Inc(B);
- Str(B:3,E);
- for j:=1 to Length(E) do if E[j]=' ' then E[j]:='0';
- E:='.'+E;
- FNi:=D+N+E;
- end;{L_CloseArchiv}
-
-
- var
- FileOpened:Boolean;
- NewFile:Boolean;
- InitNewFile:Boolean;
- OutBytes:LongInt;
- FBytes:LongInt;
- FSize:LongInt;
- FSizeChar:String[5];
- Bytes:Byte;
- CompressFlag,CompressByte:Byte;
-
- procedure L_BlockProcess(W:Word);
- var
- B:Byte;
- i,j:Word;
- Count:Word;
- FName,Di,Na,Ex:PathStr;
- Po:Byte;
- begin {L_BlockProcess}
- i:=0;
- repeat
- Inc(i);
- B:=iBuf[i];
- if NewFile then begin
- if InitNewFile then begin
- Bytes:=B+4; {4 file len}
- FSizeChar:='';
- FNo:=OutDir;
- FName:='';
- InitNewFile:=false;
- end else begin {ProcessNewFile}
- if Bytes>4 then begin {get file name}
- FNo:=FNo+Char(B);
- FName:=FName+Char(B);
- Dec(Bytes);
- end else if Bytes>0 then begin {get file size}
- FSizeChar:=FSizeChar+Char(B);
- Dec(Bytes);
- end else begin {open new file}
- Write(cr_lf,' ',FNo);
- Assign(Fo,FNo);
- ReWrite(Fo,1);
- if IoResult<>0 then begin {attempt create directory, if exist}
- FSplit(FName,Di,Na,Ex);
- if Di='' then Abort(not_create+FNo) {not a directory}
- else begin
- Na:=''; {working directory names}
- while Di<>'' do begin
- Po:=Pos('\',Di); {find subdirs}
- Na:=Na+Copy(Di,1,Po-1);
- if Po<Length(Di) then Di:=Copy(Di,Po+1,Length(Di)-Po) else Di:='';
- MkDir(OutDir+Na);
- Na:=Na+'\';
- end;{while}
- ReWrite(Fo,1);
- if IoResult<>0 then Abort(not_create+FNo);
- end;{if}
- end;{if}
- Move(FSizeChar[1],FSize,4);
- FBytes:=0;
- NewFile:=false;
- Dec(i);
- if FSize=0 then begin {file length = 0}
- Close(Fo);
- if IoResult<>0 then Abort(not_close+FNo);
- NewFile:=true;
- InitNewFile:=true;
- OutBytes:=1;
- end;{if}
- end;{if}
- end;{if,InitNewFile}
- end else begin {------------------------------------------- append byte }
- if CompressFlag=1 then begin {save compress byte}
- CompressByte:=B;
- Inc(CompressFlag);
- end else if CompressFlag=2 then begin {uncompress}
- CompressFlag:=0;
- FillChar(oBuf[OutBytes],B,CompressByte);
- Inc(OutBytes,B);
- Inc(FBytes,B);
- end else if B=c_byte then CompressFlag:=1
- else begin
- oBuf[OutBytes]:=B;
- if OutBytes>=(BufSize-512) then begin {WriteBlock}
- BlockWrite(Fo,oBuf,OutBytes,Count);
- if (IoResult<>0)or(OutBytes<>Count) then Abort(not_write+FNo);
- OutBytes:=0;
- end;{if}
- Inc(OutBytes);
- Inc(FBytes);
- end;{if}
- if FSize<=FBytes then begin {close file}
- Dec(OutBytes);
- BlockWrite(Fo,oBuf,OutBytes,Count);
- if (IoResult<>0)or(OutBytes<>Count) then Abort(not_write+FNo);
- Close(Fo);
- if IoResult<>0 then Abort(not_close+FNo);
- NewFile:=true;
- InitNewFile:=true;
- OutBytes:=1;
- end;{if}
- end;{if,NewFile}
- until i>=W;
- end;{L_BlockProcess}
-
-
- procedure L_ReadArchiv;
- var
- Count:Word;
- W,EofArchiv:LongInt;
- begin {L_ReadArchiv}
- EofArchiv:=FileSize(Fi)-2;
- while FilePos(Fi)<EofArchiv do begin {}
- W:=EofArchiv-FilePos(Fi);
- if W>BufSize then W:=BufSize;
- BlockRead(Fi,iBuf,W,Count);
- if (IoResult<>0)or(W<>Count) then Abort(not_read+FNi);
- L_BlockProcess(W);
- end;{while,FilePos}
- end;{L_ReadArchiv}
-
-
- var
- PFirst,I,Code:Integer;
-
-
- begin {MAIN, Archiv}
- System.FileMode:=$40; {read_only, deny_none, inherited bu spawn...}
- UpPressKey:=press_key; {"press any key..."}
- UpPressKey[1]:=UpCase(UpPressKey[1]); {"Press any key..."}
- if ParamCount>=2 then begin
- PFirst:=1; {assume, index into first parameter}
- S:=StUpCase(ParamStr(PFirst));
- if Copy(S,1,2)='/W' then begin {window switch, shift parameters}
- Window(6,5,75,Mem[$0040:$0084]-3);
- Val(Copy(S,3,Length(S)-2),I,Code);
- if Code=0 then TextAttr:=I
- else if LastMode=7 then TextAttr:=$07 else TextAttr:=$1E; {bg+/b}
- ClrScr;
- PFirst:=2; {shift}
- S:=StUpCase(ParamStr(PFirst));
- end;{if}
- end;{if}
- Write('Archiv v2.03 Backup/Restore database utility');
- Write(cr_lf,'Copyright (c) 1991, JHK, JHK-Software, Piestany. All rights reserved.');
- if ParamCount<2 then AbortPars;
- if Copy(S,1,2)='/S' then begin
- FSplit(FExpand(ParamStr(ParamCount)),D,N,E);
- if N='' then N:='Archiv';
- E:='.001';
- FNo:=D+N+E;
- for I:=PFirst+1 to ParamCount-1 do S_SaveMask(ParamStr(I)); {main save loop}
- if ArchOpened then S_CloseArchiv(false);
- end else begin
- FSplit(FExpand(ParamStr(PFirst+1)),D,N,E);
- if N='' then N:='Archiv';
- E:='.001';
- FNi:=D+N+E;
- OutDir:=FExpand(ParamStr(PFirst+2));
- if OutDir[Length(OutDir)]<>'\' then OutDir:=OutDir+'\';
- {}
- NewFile:=true;
- InitNewFile:=true;
- OutBytes:=1;
- FBytes:=0;
- FSize:=0;
- CompressFlag:=0;
- repeat
- L_OpenArchiv;
- L_ReadArchiv;
- until L_CloseArchiv;
- end;{if}
- Write(cr_lf,done);
- Write(cr_lf,UpPressKey);
- ReadKey;
- end.
-
-